-- LDB data object with an optional internal frame.
local _, Skada = ...
local L = LibStub("AceLocale-3.0"):GetLocale("Skada", false)

local name = L["Data text"]
local mod = Skada:NewModule(name)
local ldb = LibStub:GetLibrary("LibDataBroker-1.1")

local libwindow = LibStub("LibWindow-1.1")
local media = LibStub("LibSharedMedia-3.0")

mod.name = name
mod.description = L["Data text acts as an LDB data feed. It can be integrated in any LDB display such as Titan Panel or ChocolateBar. It also has an optional internal frame."]
Skada:AddDisplaySystem("broker", mod)

local function sortDataset(win)
	table.sort(win.dataset, function (a, b)
		if not a or a.value == nil then
			return false
		elseif not b or b.value == nil then
			return true
		else
			return a.value > b.value
		end
	end)
end

local function formatLabel(win, data)
	local label = ""
	if win.db.isusingclasscolors and data.class then
		label = "|c"
		label = label..RAID_CLASS_COLORS[data.class].colorStr
		label = label..data.label
		label = label.."|r"
	else
		label = data.label
	end
	return label
end

local function formatValue(win, data)
	return data.valuetext
end

local function clickHandler(win, frame, button)
	if not win.obj then
		return
	end

	if button=="LeftButton" and IsShiftKeyDown() then
		Skada:OpenMenu(win)
	elseif button=="LeftButton" then
		Skada:ModeMenu(win)
	elseif button=="RightButton" then
		Skada:SegmentMenu(win)
	end
end

local function tooltipHandler(win, tooltip)
	if win.db.useframe then
		Skada:SetTooltipPosition(tooltip, win.frame)
	end

	-- Default color.
	local color = win.db.textcolor

	tooltip:AddLine(win.metadata.title)
	tooltip:AddLine(" ")

	sortDataset(win)
	if #win.dataset > 0 then
		for i, data in ipairs(win.dataset) do
			if data.id and not data.ignore and i < 30 then
				local label = formatLabel(win, data)
				local value = formatValue(win, data)

				if win.metadata.showspots and Skada.db.profile.showranks then
					label = (("%2u. %s"):format(i, label))
				end

				tooltip:AddDoubleLine(label or "", value or "", color.r, color.g, color.b, color.r, color.g, color.b)

			end
		end
	end

	tooltip:AddLine(" ")
	tooltip:AddLine(L["Hint: Left-Click to set active mode."], 0, 1, 0)
	tooltip:AddLine(L["Right-click to set active set."], 0, 1, 0)
	tooltip:AddLine(L["Shift + Left-Click to open menu."], 0, 1, 0)

	tooltip:Show()
end

local ttactive = false

function mod:Create(win, isnew)
	-- Optional internal frame
	if not win.frame then
		win.frame = CreateFrame("Frame", win.db.name.."BrokerFrame", UIParent)
		win.frame:SetHeight(win.db.height or 30)
		win.frame:SetWidth(win.db.width or 200)
		win.frame:SetPoint("CENTER", 0, 0)

		-- Register with LibWindow-1.1.
		libwindow.RegisterConfig(win.frame, win.db)

		-- Restore window position.
		if isnew then
			libwindow.SavePosition(win.frame)
		else
			libwindow.RestorePosition(win.frame)
		end

		local title = win.frame:CreateFontString("frameTitle", 6)
		title:SetPoint("CENTER", 0, 0)
		win.frame.title = title

		win.frame:EnableMouse(true)
		win.frame:SetMovable(true)
		win.frame:RegisterForDrag("LeftButton")
		win.frame:SetScript("OnMouseUp", function(frame, button)
			clickHandler(win, frame, button)
		end)
		win.frame:SetScript("OnEnter", function(frame)
			tooltipHandler(win, GameTooltip)
		end)
		win.frame:SetScript("OnLeave", function(frame)
			GameTooltip:Hide()
		end)
		win.frame:SetScript("OnDragStart", function(frame)
			if not win.db.barslocked then
				GameTooltip:Hide()
				frame.isDragging = true
				frame:StartMoving()
			end
		end)
		win.frame:SetScript("OnDragStop", function(frame)
			frame:StopMovingOrSizing()
			frame.isDragging = false
			libwindow.SavePosition(frame)
		end)

	end

	-- LDB object
	if not win.obj then
		win.obj = ldb:NewDataObject('Skada: '..win.db.name, {
			type = "data source",
			text = "",
			OnTooltipShow = function (tooltip)
				tooltipHandler(win, tooltip)
			end,
			OnClick = function(frame, button)
				clickHandler(win, frame, button)
			end
		})
	end

	mod:ApplySettings(win)
end

function mod:IsShown(win)
	return win.frame:IsShown()
end

function mod:Show(win)
	if win.db.useframe then
		win.frame:Show()
	end
end

function mod:Hide(win)
	if win.db.useframe then
		win.frame:Hide()
	end
end

function mod:Destroy(win)
	win.obj.text = " "
	win.obj = nil
	win.frame:Hide()
	win.frame = nil
end

function mod:Wipe(win)
	win.text = " "
end

function mod:SetTitle(win, title)
end

function mod:Update(win)
	if win.obj then
		win.obj.text = ""
	end
	sortDataset(win)
	if #win.dataset > 0 then
		local data = win.dataset[1]
		if data.id then
			local label = (formatLabel(win, data) or "").." - "..(formatValue(win, data) or "")

			if win.obj then
				win.obj.text = label
			end
			if win.db.useframe then
				win.frame.title:SetText(label)
			end
		end
	end
end

function mod:OnInitialize()
end

function mod:ApplySettings(win)
	if win.db.useframe then
		local title = win.frame.title
		local db = win.db

		win.frame:SetMovable(not win.db.barslocked)
		win.frame:SetHeight(win.db.height or 30)
		win.frame:SetWidth(win.db.width or 200)
		local fbackdrop = {}
		fbackdrop.bgFile = media:Fetch("background", db.background.texture)
		fbackdrop.tile = db.background.tile
		fbackdrop.tileSize = db.background.tilesize
		win.frame:SetBackdrop(fbackdrop)
		win.frame:SetBackdropColor(db.background.color.r,db.background.color.g,db.background.color.b,db.background.color.a)

		Skada:ApplyBorder(win.frame, db.background.bordertexture, db.background.bordercolor, db.background.borderthickness)

		title:SetTextColor(db.textcolor.r,db.textcolor.g,db.textcolor.b,db.textcolor.a)
		title:SetFont(media:Fetch('font', db.barfont), db.barfontsize, db.barfontflags)
		title:SetText(win.metadata.title or "Skada")
		title:SetWordWrap(false)
		title:SetJustifyH("CENTER")
		title:SetJustifyV("MIDDLE")
		title:SetHeight(win.db.height or 30)

		win.frame:SetScale(db.scale)
		win.frame:SetFrameStrata(db.strata)
	else
		win.frame:Hide()
	end
	self:Update(win)
end

function mod:AddDisplayOptions(win, options)
	local db = win.db
	options.main = {
		type = "group",
		name = "Datatext",
		order = 3,
		args = {

			useframe = {
				type = 'toggle',
				name = "Use frame",
				desc = "Shows a standalone frame. Not needed if you are using an LDB display provider such as Titan Panel or ChocolateBar.",
				get = function() return db.useframe end,
				set = function(win,key)
					db.useframe = key
					Skada:ApplySettings()
				end,
				order=0.0,
			},

			classcolortext = {
					type="toggle",
					name=L["Class color text"],
					desc=L["When possible, bar text will be colored according to player class."],
					order=0.1,
					get=function() return db.isusingclasscolors end,
					set=function()
							db.isusingclasscolors = not db.isusingclasscolors
							Skada:ApplySettings()
						end,
			},
			color = {
				type="color",
				name=L["Text color"],
				desc=L["Choose the default color."],
				hasAlpha=true,
				get=function(i)
						local c = db.textcolor
						return c.r, c.g, c.b, c.a
					end,
				set=function(i, r,g,b,a)
						db.textcolor = {["r"] = r, ["g"] = g, ["b"] = b, ["a"] = a}
						Skada:ApplySettings()
					end,
				order=4,
			},

			barfont = {
				type = 'select',
				dialogControl = 'LSM30_Font',
				name = L["Bar font"],
				desc = L["The font used by all bars."],
				values = AceGUIWidgetLSMlists.font,
				get = function() return db.barfont end,
				set = function(win,key)
					db.barfont = key
					Skada:ApplySettings()
				end,
				order=1,
			},

			barfontsize = {
				type="range",
				name=L["Bar font size"],
				desc=L["The font size of all bars."],
				min=7,
				max=40,
				step=1,
				get=function() return db.barfontsize end,
				set=function(win, size)
					db.barfontsize = size
					Skada:ApplySettings()
				end,
				order=2,
			},

			barfontflags = {
				type = 'select',
				name = L["Font flags"],
				desc = L["Sets the font flags."],
				values = {[""] = L["None"], ["OUTLINE"] = L["Outline"], ["THICKOUTLINE"] = L["Thick outline"], ["MONOCHROME"] = L["Monochrome"], ["OUTLINEMONOCHROME"] = L["Outlined monochrome"]},
				get = function() return db.barfontflags end,
				set = function(win,key)
					db.barfontflags = key
					Skada:ApplySettings()
				end,
				order=3,
			},

		}
	}

	options.window = Skada:FrameSettings(db, true)
end
